#include "stdafx.h"
#include "Tank.h"
#include "Utils.h"
#include "Globals.h"
#include "Marco.h"

Tank::Tank() : Entity()
{
}

Tank::Tank(char* filename) : Entity()
{
	FILE * pFile;
	fopen_s(&pFile, filename, "r");

	if (pFile == NULL)
	{
		fputs("File error: ", stderr);
		return;
	}

	char buffer[MAX_LENGTH];

	// Read name of models
	ReadLine(pFile, buffer);
	Name = new char[strlen(buffer) + 1];
	strcpy_s(Name, strlen(buffer) + 1, buffer);
	//

	char** m_Paths;
	m_Paths = new char*[3];
	for (int i = 0; i < 3; i++)
	{
		m_Paths[i] = new char[MAX_LENGTH];
		ReadLine(pFile, buffer);
		strcpy(m_Paths[i], buffer);
	}
	Load_Collada(m_Paths[0], m_Paths[1], m_Paths[2]);

	for (int i = 0; i < 3; i++)
		delete[] m_Paths[i];
	delete[] m_Paths;


	ReadLine(pFile, buffer);
	int iPos = 0;
	int m_Value;
	while (buffer[iPos] != '\0')
	{
		iPos = ScanNumberInt32(buffer, &m_Value, iPos);
		m_ObjectsHead.push_back(m_Value);
	}

	ReadLine(pFile, buffer);
	iPos = 0;
	while (buffer[iPos] != '\0')
	{
		iPos = ScanNumberInt32(buffer, &m_Value, iPos);
		m_ObjectsBody.push_back(m_Value);
	}
	for (int i = 0; i < m_NumModel; i++)
	{
		// Position1
		ReadLine(pFile, buffer);
		int iPos = 0;
		iPos = ScanNumberFloat32(buffer, &m_Models[i]->m_Position.x, iPos);
		iPos = ScanNumberFloat32(buffer, &m_Models[i]->m_Position.y, iPos);
		iPos = ScanNumberFloat32(buffer, &m_Models[i]->m_Position.z, iPos);

		// m_Scale
		ReadLine(pFile, buffer);
		iPos = 0;
		iPos = ScanNumberFloat32(buffer, &m_Models[i]->m_Scale.x, iPos);
		iPos = ScanNumberFloat32(buffer, &m_Models[i]->m_Scale.y, iPos);
		iPos = ScanNumberFloat32(buffer, &m_Models[i]->m_Scale.z, iPos);

		// Rotation
		ReadLine(pFile, buffer);
		iPos = 0;
		iPos = ScanNumberFloat32(buffer, &m_Models[i]->m_Rotate.x, iPos);
		iPos = ScanNumberFloat32(buffer, &m_Models[i]->m_Rotate.y, iPos);
		iPos = ScanNumberFloat32(buffer, &m_Models[i]->m_Rotate.z, iPos);
	}
	

}

void Tank::draw()
{
	glUseProgram(m_Shader->program);
	for (int i = 0; i < m_NumModel; i++)
	{
		m_Models[i]->draw(m_Shader);
		const unsigned int MaterialIndex = m_Models[i]->getTextureID();
		int index = MaterialIndex * 2;
		if (MaterialIndex < m_NumTextures && m_Textures[MaterialIndex])
		{
			m_Textures[index]->Bind(GL_TEXTURE0);
			m_Textures[index + 1]->Bind(GL_TEXTURE1);
		}

		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_Models[i]->IND);
		glDrawElements(GL_TRIANGLES, m_Models[i]->getNumIndices(), GL_UNSIGNED_SHORT, 0);

		m_Textures[index]->UnBind(GL_TEXTURE0);
		m_Textures[index + 1]->UnBind(GL_TEXTURE1);
	}
	
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}


void Tank::update(float deltatime)
{
	/*for (int i = 0; i < m_NumModel; i++)
		m_Models[i]->m_Rotate.y += 0.01f;*/
}

Tank::~Tank()
{
}


void Tank::MoveForward(float speed)
{
	Vector3 deltaMove = -(m_Position - target).Normalize()*speed;
	m_Position += deltaMove;
	target += deltaMove;
	gunPositon += deltaMove;
	targetShot += deltaMove;
	this->SetPostion(m_Position);
}

void Tank::MoveBackward(float speed)
{
	Vector3 deltaMove = (m_Position - target).Normalize()*speed;
	m_Position += deltaMove;
	target += deltaMove;
	gunPositon += deltaMove;
	targetShot += deltaMove;
	this->SetPostion(m_Position);
}

void Tank::RotateLeft(float offset)
{
	float offsetX = 0.00f;
	rotateAngleGun.y += (offset + offsetX);
	if (rotateAngleGun.y > 3.14f)
		rotateAngleGun.y = -3.14f;
	int count = this->m_ObjectsHead.size();
	for (int i = 0; i < count; i++)
	{
		this->m_Models[this->m_ObjectsHead[i]]->m_Rotate.y += offset;
		if (this->m_Models[this->m_ObjectsHead[i]]->m_Rotate.y>3.14f)
			this->m_Models[this->m_ObjectsHead[i]]->m_Rotate.y = -3.14f;
		//rotateAngleGun.y = this->m_Models[this->m_ObjectsHead[i]]->m_Rotate.y;
	}
	//Vector4 newTarget = Vector4()
	Vector4 temp = Vector4(targetShot.x, targetShot.y, targetShot.z, 1.0f);
	Vector4 newGunPos = Vector4(gunPositon.x, gunPositon.y, gunPositon.z, 1.0f);
	/*Matrix translate = Matrix().SetTranslation(tankPos.x, tankPos.y, tankPos.z);
	*/
	Matrix RotationX, RotationY, RotationZ;
	RotationX.SetIdentity();
	RotationY.SetIdentity();
	RotationZ.SetIdentity();
	RotationX.SetRotationX(rotateAngleGun.x);
	RotationY.SetRotationY(rotateAngleGun.y);
	RotationZ.SetRotationZ(rotateAngleGun.z);
	Matrix Rotation = RotationZ*RotationX*RotationY;

	Vector4 newTag = temp*Rotation;
	Vector4 newGun = newGunPos*Rotation;
	gunPositon = Vector3(newGun.x, newGun.y, newGun.z);
	targetShot = Vector3(newTag.x, newTag.y, newTag.z);
}

void Tank::RotateRight(float offset)
{
	float offsetX = 0.00f;
	rotateAngleGun.y -= (offset+offsetX);
	if (rotateAngleGun.y < -3.14f)
		rotateAngleGun.y=3.14f;

	int count = this->m_ObjectsHead.size();
	for (int i = 0; i < count; i++)
	{
		this->m_Models[this->m_ObjectsHead[i]]->m_Rotate.y -= offset;
		if (this->m_Models[this->m_ObjectsHead[i]]->m_Rotate.y<-3.14f)
			this->m_Models[this->m_ObjectsHead[i]]->m_Rotate.y = 3.14f;
		//rotateAngleGun.y = this->m_Models[this->m_ObjectsHead[i]]->m_Rotate.y;
	}
	//Vector4 temp = Vector4(gunPositon.x, gunPositon.y, gunPositon.z, 1.0f);

	///*Matrix translate = Matrix().SetTranslation(tankPos.x, tankPos.y, tankPos.z);
	//*/
	//Matrix RotationX, RotationY, RotationZ;
	//RotationX.SetIdentity();
	//RotationY.SetIdentity();
	//RotationZ.SetIdentity();
	//RotationX.SetRotationX(rotateAngleGun.x);
	//RotationY.SetRotationY(rotateAngleGun.y);
	//RotationZ.SetRotationZ(rotateAngleGun.z);
	//Matrix Rotation = RotationZ*RotationX*RotationY;

	//Vector4 newTag = temp*Rotation;
	//gunPositon = Vector3(newTag.x, newTag.y, newTag.z);
	Vector4 temp = Vector4(targetShot.x, targetShot.y, targetShot.z, 1.0f);
	Vector4 newGunPos = Vector4(gunPositon.x, gunPositon.y, gunPositon.z, 1.0f);
	/*Matrix translate = Matrix().SetTranslation(tankPos.x, tankPos.y, tankPos.z);
	*/
	Matrix RotationX, RotationY, RotationZ;
	RotationX.SetIdentity();
	RotationY.SetIdentity();
	RotationZ.SetIdentity();
	RotationX.SetRotationX(rotateAngleGun.x);
	RotationY.SetRotationY(rotateAngleGun.y);
	RotationZ.SetRotationZ(rotateAngleGun.z);
	Matrix Rotation = RotationZ*RotationX*RotationY;

	Vector4 newTag = temp*Rotation;
	Vector4 newGun = newGunPos*Rotation;
	gunPositon = Vector3(newGun.x, newGun.y, newGun.z);
	targetShot = Vector3(newTag.x, newTag.y, newTag.z);
}


void Tank::MoveLeft(float speed)
{
	if (hasRotateBody==5)
	{
		MoveForward(speed);
		hasRotateBody = 0;
		isMoveLeft = false;
	}
	else
	{
		int count = this->m_ObjectsBody.size();
		for (int i = 0; i < count; i++)
		{
			this->m_Models[this->m_ObjectsBody[i]]->m_Rotate.y += 0.1f;
			if (this->m_Models[this->m_ObjectsBody[i]]->m_Rotate.y>3.14f)
				this->m_Models[this->m_ObjectsBody[i]]->m_Rotate.y = -3.14f;
		}
		hasRotateBody ++;
		Matrix RotationX, RotationY, RotationZ;
		RotationX.SetIdentity();
		RotationY.SetIdentity();
		RotationZ.SetIdentity();
		RotationX.SetRotationX(0.0f);
		RotationY.SetRotationY(0.05f);
		RotationZ.SetRotationZ(0.0f);
		Matrix Rotation = RotationZ*RotationX*RotationY;
		Vector4 newTarget = Vector4(target, 1.0)*Rotation;
		target = Vector3(newTarget.x, newTarget.y, newTarget.z);
		//Sleep(300);
	}
}